/*
 * player.c
 *
 *  Created on: 15 nov. 2010
 *      Author: Nicolas Aucouturier, Laurent Reveillere
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>
#include "SDL.h"
#include "SDL_image.h"

#include "../include/game.h"
#include "../include/misc.h"
#include "../include/bomb.h"
#include "../include/list_bomb.h"

struct s_player {
	int x, y;
	SDL_Surface * directed_img[4];
	enum e_way current_way;
	int nb_life;
	int nb_bomb;
};

t_player player_init(int bomb_number,int life_number) {
	t_player player = malloc(sizeof(*player));
	if (!player)
		error("Memory error");


	player->directed_img[WEST] = load_image(IMG_PLAYER_LEFT);
	player->directed_img[EAST] = load_image(IMG_PLAYER_RIGHT);
	player->directed_img[NORTH] = load_image(IMG_PLAYER_UP);
	player->directed_img[SOUTH] = load_image(IMG_PLAYER_DOWN);





	player->current_way = SOUTH;
	player->nb_bomb = bomb_number;
	player->nb_life = life_number;
	return player;
}

void player_free(t_player player) {
	assert(player);
	int i;
	for (i = 0; i < 4; i++)
		SDL_FreeSurface(player->directed_img[i]);

	free(player);
}

int player_get_x(t_player player) {
	assert(player != NULL);
	return player->x;
}

int player_get_y(t_player player) {
	assert(player != NULL);
	return player->y;
}

void player_set_current_way(t_player player, enum e_way way) {
	assert(player);
	player->current_way = way;
}

//FIXME
void player_set_x(t_player player, int x) {
	assert(player != NULL);
	player->x=x;
}

void player_set_y(t_player player, int y) {
	assert(player != NULL);
	player->y=y;
}

SDL_Surface * player_get_directed_img(t_player player, enum e_way current_way) {
	assert(player);
	return player->directed_img[current_way];
}

//New enum
enum e_way player_get_current_way(t_player player) {
	assert(player);
	return player->current_way;
}


int player_get_nb_bomb(t_player player) {
	assert(player);
	return player->nb_bomb;
}

void player_inc_nb_bomb(t_player player) {
	assert(player);
	player->nb_bomb += 1;
}

void player_dec_nb_bomb(t_player player) {
	assert(player);
	player->nb_bomb -= 1;
}

// Life of player
int player_get_nb_life(t_player player) {
	assert(player);
	return player->nb_life;
}

void player_inc_nb_life(t_player player) {
	assert(player);
	player->nb_life += 1;
}

void player_dec_nb_life(t_player player) {
	assert(player);
	player->nb_life -= 1;
}

void player_from_map(t_player player, t_map map) {
	int i, j;
	for (i = 0; i < map_get_width(map); i++) {
		for (j = 0; j < map_get_height(map); j++) {
			if (map_get_cell_type(map, i, j) == CELL_PLAYER) {
				player->x = i;
				player->y = j;
			}
		}
	}
}

static int player_move_aux(t_player player, t_map map, int x1, int y1, int x2,
		int y2) {

	if (!map_is_inside(map, x1, y1))
		return 0;

	switch (map_get_cell_type(map, x1, y1)) {
	case CELL_SCENERY:
		return 0; //0 to avoid collision with scenery (trees, rocks,..)
		break;

	case CELL_CASE:
		return 0; // 0 to avoid collision with boxes
		break;

	case CELL_BONUS:
		break;

	case CELL_GOAL:
		break;

	case CELL_MONSTER:
		break;

	case CELL_PLAYER:
		break;

	default:
		break;
	}

	// Player has moved
	return 1;
}

int player_move(t_player player, t_map map) {
	int x = player->x;
	int y = player->y;
	int move = 0;

	switch (player->current_way) {
	case NORTH:
		if (player_move_aux(player, map, x, y - 1, x, y - 2)) {
			player->y--;

			//if (y<=0) {player->y++;}//Joueur bloqué par le Nord

			move = 1;
		}
		break;

	case SOUTH:
		if (player_move_aux(player, map, x, y + 1, x, y + 2)) {
			player->y++;

			//if (y>=map_get_height(map)-1) {player->y--;}//Joueur bloqué par le Sud

			move = 1;
		}
		break;

	case WEST:
		if (player_move_aux(player, map, x - 1, y, x - 2, y)) {
			player->x--;

			//if (x<=0) {player->x++;}//Joueur bloqué par l'Ouest

			move = 1;
		}
		break;

	case EAST:
		if (player_move_aux(player, map, x + 1, y, x + 2, y)) {
			player->x++;

			//if (x>=(map_get_width(map)-1)) {player->x--;}//Joueur bloqué par l'Est

			move = 1;
		}
		break;
	}

	//La mise en commentaires suivante permet de pouvoir prendre les escaliers (passer sur la case des escaliers sans les faire disparaître)
	/*
	if (move) {
		map_set_cell_type(map, x, y, CELL_EMPTY);
		map_set_cell_type(map, player->x, player->y, CELL_PLAYER);
	}
	*/
	return move;
}

void player_display(t_player player, SDL_Surface *screen) {
	assert(player);
	assert(player->directed_img[player->current_way]);
	assert(screen);

	SDL_Rect place;
	place.x = player->x * SIZE_BLOC;
	place.y = player->y * SIZE_BLOC;

	SDL_BlitSurface(player->directed_img[player->current_way], NULL, screen,
			&place);
}

